﻿using AiQiuQuan.Sport.Model;
using AiQiuQuan.Sport.Model.Models;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using EasyCaching.Core;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// UserTokenService
    /// </summary>
    public class UserTokenService : IUserTokenService
    {
        private readonly JwtOption _jwtOption;
        private readonly IEasyCachingProvider _cache;

        /// <summary>
        /// ctor
        /// </summary>
        public UserTokenService(
            IOptions<JwtOption> options,
            IEasyCachingProvider cache)
        {
            _jwtOption = options.Value;
            _cache = cache;
        }

        /// <summary>
        /// 获取用户token
        /// </summary>
        public async Task<UserTokenResultDto> CreateTokenAsync(UserTokenRequestDto request)
        {
            var result = new UserTokenResultDto { Expire = _jwtOption.Expires, RefreshExpire = _jwtOption.RefreshTokenExpires };
            var start = DateTime.Now;

            //刷新token缓存
            var refreshToken = Guid.NewGuid().ToString();
            await _cache.SetAsync(request.UserId.ToString(), refreshToken, TimeSpan.FromSeconds(_jwtOption.RefreshTokenExpires));

            var signinCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOption.SecurityKey)), SecurityAlgorithms.HmacSha256);
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, request.MiniProgramOpenId),
                new Claim("id", request.UserId.ToString()),
                new Claim(JwtRegisteredClaimNames.Name, request.NickName ?? string.Empty),
            };
            var jwt = new JwtSecurityToken(
                issuer: _jwtOption.Issuer,
                audience: _jwtOption.Audience,
                claims: claims,
                notBefore: start,
                expires: start.AddSeconds(_jwtOption.Expires),
                signingCredentials: signinCredentials
            );
            var token = new JwtSecurityTokenHandler().WriteToken(jwt);

            result.UserToken = token;
            result.RefreshToken = refreshToken;
            return result;
        }
    }
}
